import ij.IJ;
import ij.ImagePlus;
import ij.io.FileSaver;
import ij.plugin.PlugIn;
import ij.process.ByteProcessor;
import ij.process.ImageProcessor;
import ij.process.ShortProcessor;
import ij.umasuo.MyConstants;
import ij.umasuo.AOTFController.DStormCtr;
import ij.umasuo.AOTFController.LiveCtr;
import ij.umasuo.AOTFController.StormCtr;

import java.io.File;

import mmcorej.CMMCore;

import org.micromanager.MMStudioMainFrame;


/**
 * this is a the camera we used to controller the camera.
 * this plugin can only be used in the micro-manager
 * @author liuquan
 * @date 2013-08-21
 * @version 1.0
 */
public class CameraPlugin implements PlugIn{
	public static CMMCore core = null;
	
	private boolean initCore(){
		MMStudioMainFrame gui = MMStudioMainFrame.getInstance();
		if(gui == null){return false;}
		core = gui.getCore();
		if(core == null){return false;}
		if(gui.isLiveModeOn()){
			gui.enableLiveMode(false);
		}
		
		return true;
	}
	/**
	 * here we hand the two kind of situation:dstorm & storm
	 */
	@Override
	public void run(String arg) {
		IJ.register(CameraPlugin.class);
		if(arg == null || !initCore()){
			return;
		}
		String[] args = arg.split(":");
		if(args.length <=0){
			return;
		}
		try{
			if(args[0].equals("dstorm")){
				core.startContinuousSequenceAcquisition(0.0);
				while(DStormCtr.isTakingData() ){
//					IJ.log("taking data in plugin....");
					if(core.getRemainingImageCount() > 0 && MyConstants.isCanTakingDate){
						Object img = core.popNextImage();
						ImageProcessor ip = null;
						if (img instanceof byte[]) {
							ip = new ByteProcessor((int)core.getImageWidth(), (int)core.getImageHeight());
							ip.setPixels((byte[]) img);
						} else if (img instanceof short[]) {
							ip = new ShortProcessor((int)core.getImageWidth(), (int)core.getImageHeight());
							ip.setPixels((short[]) img);
						} else {
							IJ.error("DSTORM ERROR","Image Type Error");
							System.exit(-1);
						}
						//save images to the hard disk
						ImageProcessor ip2 = ip.duplicate();
						ImagePlus imp = new ImagePlus("" + DStormCtr.getInstance().getCurCount(), ip2);
						FileSaver fs = new FileSaver(imp);
						File file = new File(MyConstants.getFileSavePath());
						if (!file.exists()) {
							file.mkdirs();
						}
						fs.saveAsTiff(MyConstants.getFileSavePath() + DStormCtr.getInstance().getCurCount() + ".tif");
						DStormCtr.getInstance().addImage(MyConstants.getFileSavePath() + DStormCtr.getInstance().getCurCount() + ".tif");//save the image's path to the memery
					}else{
						Thread.currentThread().sleep(500);
					}
				}
				core.stopSequenceAcquisition();
			}else if(args[0].equals("storm")){
				int channel = Integer.parseInt(args[1]);
				core.snapImage();// Snap
				Object img = core.getImage();
				ImageProcessor ip = null;
				if (img instanceof byte[]) {
					ip = new ByteProcessor((int)core.getImageWidth(), (int)core.getImageHeight());
					ip.setPixels((byte[]) img);
				} else if (img instanceof short[]) {
					ip = new ShortProcessor((int)core.getImageWidth(), (int)core.getImageHeight());
					ip.setPixels((short[]) img);
				} else {
					IJ.error("DSTORM ERROR","Image Type Error");
					System.exit(-1);
				}
				
				//save images to the hard disk
				ImageProcessor ip2 = ip.duplicate();
				ImagePlus imp = new ImagePlus("" + StormCtr.getInstance().getChanCount(channel), ip2);
				FileSaver fs = new FileSaver(imp);
				File file = new File(MyConstants.getFileSavePath() + channel + "\\");
				if (!file.exists()) {
					file.mkdirs();
				}
				fs.saveAsTiff(MyConstants.getFileSavePath() + channel + "\\" + StormCtr.getInstance().getChanCount(channel) + ".tif");
				StormCtr.getInstance().addImage(MyConstants.getFileSavePath() + channel + "\\" + StormCtr.getInstance().getChanCount(channel) + ".tif" + ".tif",channel);
			}else if(args[0].equals("live")){
				core.clearCircularBuffer();
				core.startContinuousSequenceAcquisition(0.0);
				while(LiveCtr.getInstance().isLivingON()){
					if(core.getRemainingImageCount() > 0){
						Object img = core.popNextImage();
						ImageProcessor ip = null;
						if (img instanceof byte[]) {
							ip = new ByteProcessor((int)core.getImageWidth(), (int)core.getImageHeight());
							ip.setPixels((byte[]) img);
						} else if (img instanceof short[]) {
							ip = new ShortProcessor((int)core.getImageWidth(), (int)core.getImageHeight());
							ip.setPixels((short[]) img);
						} else {
							IJ.error("DSTORM ERROR","Image Type Error");
							System.exit(-1);
						}
						//save images to the hard disk
						ImagePlus imp = new ImagePlus("live", ip);
						LiveCtr.getInstance().setImage(imp);
					}
					Thread.currentThread().sleep(20);
				}
				core.stopSequenceAcquisition();
			}else{
				core.clearCircularBuffer();
				core.startContinuousSequenceAcquisition(0.0);
				int count = 10000;
				IJ.log("get in");
				long starttime = System.currentTimeMillis();
				while(count >0){
					if(core.getRemainingImageCount() > 0){
						Object img = core.popNextImage();
						ImageProcessor ip = null;
						if (img instanceof byte[]) {
							ip = new ByteProcessor((int)core.getImageWidth(), (int)core.getImageHeight());
							ip.setPixels((byte[]) img);
						} else if (img instanceof short[]) {
							ip = new ShortProcessor((int)core.getImageWidth(), (int)core.getImageHeight());
							ip.setPixels((short[]) img);
						} else {
							IJ.error("DSTORM ERROR","Image Type Error");
							System.exit(-1);
						}
						//save images to the hard disk
						ImagePlus imp = new ImagePlus("live", ip);
//						LiveCtr.getInstance().setImage(imp);
						count --;
					}
					
				}
				long endtime = System.currentTimeMillis();
				IJ.log("" + (starttime - endtime));
				core.stopSequenceAcquisition();
			}
		}catch (Exception e){
			IJ.error(e.toString());
		}
	}
	
	

}
